package org.wevil.util;

import org.apache.commons.collections4.CollectionUtils;

import java.util.*;

/**
 * List工具类
 *
 * @author wanglei
 * @since 2021/4/16
 */
public class ListUtil {

    /**
     * 去重。删除ArrayList中重复元素，保持顺序
     *
     * @param list java.util.List
     */
    public static <E> List<E> removeDuplicateWithOrder(List<E> list) {
        // 加这一步是为了解决list如果是通过Arrays.asList()创建，没有clear()方法会导致报错：UnsupportedOperationException
        list = new ArrayList<>(list);
        Set<E> set = new HashSet<>();
        List<E> newList = new ArrayList<>();
        for (E element : list) {
            if (set.add(element)) {
                newList.add(element);
            }
        }
        list.clear();
        list.addAll(newList);
        return newList;
    }

    /**
     * 获取两个List不同的内容
     *
     * @author wanglei
     * @since 2021/6/25
     * */
    public static List<String> get2ListDifferent(List<String> list1, List<String> list2) {
        List<String> diff = new ArrayList<>();
        List<String> l1 = new ArrayList<>(list1);
        List<String> l2 = new ArrayList<>(list2);
        List<String> maxList = l1;
        List<String> minList = l2;
        if (list2.size() > list1.size()) {
            maxList = l2;
            minList = l1;
        }
        Map<String, Integer> map = new HashMap<>(maxList.size());
        for (String string : maxList) {
            map.put(string, 1);
        }
        for (String string : minList) {
            if (map.get(string) != null) {
                map.put(string, 2);
                continue;
            }
            diff.add(string);
        }
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 1) {
                diff.add(entry.getKey());
            }
        }
        return new ArrayList<>(diff);
    }

    /**
     * 获取两个集合的交集
     *
     * @author wanglei
     * @since 2021/6/25
     * */
    public static List<?> retain(List<?> list1, List<?> list2){
        list1.retainAll(list2);
        return list1;
    }

    /**
     * 两个集合取并集
     *
     * @author wanglei
     * @since 2021/6/25
     * */
    public static Collection<?> union(List<?> list1, List<?> list2){
        return CollectionUtils.union(list1, list2);
    }

    /**
     * 两个集合取差集，list-list2，
     *
     * @author wanglei
     * @since 2021/6/25
     * @return 返回list1里list2没有的元素
     * */
    public static Collection<?> subtract(List<?> list1, List<?> list2){
        return CollectionUtils.subtract(list1, list2);
    }

    /**
     * list集合拼接成以逗号分隔的字符串 a,b,c
     *
     * @author wanglei
     * @since 2022/2/28
     * */
    public static String convert2IntStr(List<Integer> list){
        String str = "";
        if(list != null && list.size()>1){
            for(Integer i : list){
                str +=  i + ",";
            }
            str = str.substring(0, str.length()-1);
        }
        if(list != null && list.size()==1){
            str = list.get(0).toString();
        }
        if(list == null){
            return null;
        }
        return str;
    }

    /**
     * 判断集合是否为空
     *
     * @author wanglei
     * @since 2021/6/25
     * */
    public static boolean isEmpty(final Collection<?> coll) {
        return coll == null || coll.isEmpty();
    }

    // ------------------------------------字符串和集合转换----------------------------------------------------//

    /**
     * list集合拼接成以逗号分隔的字符串 a,b,c
     *
     * @author wanglei
     * @since 2021/6/25
     * */
    public static String intList2Str(List<Integer> list){
        // 还可以用stream流
        return list.toString();
    }

    /**
     * 字符串数组转换为数字列表
     * @param str 字符串，示例：1,2,3
     */
    public static List<Integer> str2intList(String str) {
        if(str==null || str.length()==0){
            return null;
        }
        List<Integer> list = new ArrayList<>();
        if(str.contains(",")){
            String[] strs = str.split(",");
            Arrays.stream(strs).forEach(s -> list.add(Integer.valueOf(s)));
        }else{
            list.add(Integer.valueOf(str));
        }
        return list;
    }
}
